从使用角度解读c++20 协程

您所在的位置:网站首页 cpp20协程co yield怎么实现的 从使用角度解读c++20 协程

从使用角度解读c++20 协程

2024-06-06 19:26| 来源: 网络整理| 查看: 265

协程长什么样子

网上一堆乱七八糟的定义,看的人云里雾里,毫无意义。下面从实战角度看看协程到底长什么样子。

首先,类比线程,线程是个函数。把这个函数交给 创建线程的api,然后这个函数就变成线程了。这个函数本身没有任何特殊的地方,就是普通函数。

相比于线程,协程也是个函数,不过协程函数比线程函数讲究多了。

它必须要有返回值,返回值的类型 还必须’内嵌’一个promise_type类型promise_type类型 还必须 至少包含几个特定的实现

返回值类型最简如下:

struct task { struct promise_type { std::suspend_never initial_suspend() noexcept { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void unhandled_exception() noexcept {} task get_return_object() noexcept { return {}; } }; };

从表现形式上说,下面就是个最简协程函数:

task do_by_coroutine() {} c++20的协程三板斧

co_await、co_return、co_yield。 这3个关键字是用来控制协程运行的,那么自然只能在协程函数里面使用。他们到底是用来干什么的?

co_return

最简单最好理解的。普通函数返回用return,协程函数返回用co_return,没什么稀奇的含义,很好理解。但是用起来又比较讲究。

如果协程函数返回’void’,那么promise_type类型需要对应加一个return_void实现 struct task { struct promise_type { ... void return_void() noexcept {} //for co_return void }; }; 如果协程函数返回’值’,那么promise_type类型需要对应加一个return_value实现, 比如返回一个字符串,形参v就是返回的’值’ struct task { struct promise_type { ... void return_value(std::string&& v) noexcept {} //for co_return value }; }; co_yield

co_yield其实没必要去深入理解它,它其实是co_await的一个’变体糖’。co_yield expr 会被转化为 co_await promise.yield_value(expr),本质还是co_await。 同样co_yield用起来也比较讲究。挂起协程同时返回一个值,promise_type类型需要对应加一个yield_value实现,比如返回一个字符串,形参from就是返回的’值’

struct task { struct promise_type { ... std::suspend_always yield_value(std::string&& from) noexcept{ //for co_yield value value_ = std::move(from); return {}; } std::string value_; }; }; co_await

最后一个同时也是最讲究的关键字。 co_await expr,从这个expr必须可以得到awaitable对象。到底什么是awaitable?包含以下3个特定实现的就是awaitable,最简的awaitable定义如下:

struct awaitable { bool await_ready() noexcept { return false; } std::string await_resume() noexcept { return "123"; }; void await_suspend(std::coroutine_handle h) noexcept {}; };

最简单的使用方式:

auto value = co_await awaiter{};

上述语句怎么和awaitable的3个实现关联起来的?

首先调用await_ready,根据返回值来控制协程运行。如果返回值false,则会调用await_suspend,挂起协程,形参h表示协程对象,可以用来控制协程。如果返回值true,则会调用await_resume,返回"123"给value,不过await_ready通常为false,因为需要主动控制协程。第2步中,挂起协程后,可以调用resume在合适的时机恢复协程运行,调用resume后,await_resume会被调用,返回"123"给value。主要是步骤1->2->4,await_resume返回值也可以为空。 理解协程

协程函数必须要有返回值,且返回值类型必须符合特定要求,这个点比线程函数讲究多了。 协程三板斧关键字 也必须符合对应要求才可以使用。co_return对应return_void或者return_value,co_yield对应yield_value,co_await对应awaitable。 写点简单的示例代码,单纯从使用角度上来理解协程,其实就这么点东西。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3